﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ForTheRecord.ServiceAgents;
using NLog;
using System.IO;

namespace ForTheRecord
{
   public class FTR
   {
      private static Logger Log = LogManager.GetCurrentClassLogger();

      public string ServerName;
      public int ServerPort;

      public Boolean Connect()
      {
         Log.Debug("FTR: Connecting to server...");
         //Console.WriteLine("  Connecting to For The Record Server... ({0}:{1})", ServerName, ServerPort);
         try
         {
            ServerSettings settings = new ServiceAgents.ServerSettings();
            settings.ServerName = ServerName;
            settings.Transport = ServiceAgents.ServiceTransport.NetTcp;
            settings.Port = ServerPort;

            Boolean result = ServiceChannelFactories.Initialize(settings, true);

            if (result)
               Log.Debug("FTR: Connected.");
            else
               Log.Debug("FTR: Failed to connect to server.");

            return result;
         }
         catch (ForTheRecordNotFoundException ex)
         {
            Log.ErrorException("FTR: Exception occured.", ex);
            return false;
         }
      }

      public void ShowSchedules()
      {
         Log.Debug("FTR: Schedules:");

         using (TvSchedulerServiceAgent tvSchedulerAgent = new TvSchedulerServiceAgent())
            foreach (Entities.ScheduleSummary summary in tvSchedulerAgent.GetAllSchedules(Entities.ChannelType.Television, Entities.ScheduleType.Recording, true))
               Console.WriteLine("ID: {0}, Name: {1}", summary.ScheduleId, summary.Name);          
      }

      public void ShowProgramTitles()
      {
         Log.Debug("FTR: Program Titles:");

         using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
            foreach (Entities.RecordingGroup group in tvControlAgent.GetAllRecordingGroups(Entities.ChannelType.Television, Entities.RecordingGroupMode.GroupByProgramTitle))
            {
               Console.WriteLine("{0} (Recordings: {1}", group.ProgramTitle, group.RecordingsCount);
            }
      }

      public void ShowAllRecordingsForProgram(string programTitle, Boolean shortFilenames = false)
      {
         Log.Debug("FTR: Listing recordings for program: {0}", programTitle);

         using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
         {
            foreach (Entities.RecordingSummary summary in tvControlAgent.GetRecordingsForProgramTitle(Entities.ChannelType.Television, programTitle, false))
               if (shortFilenames)
                  Console.WriteLine("  {0}", Path.GetFileName(summary.RecordingFileName));
               else
                  Console.WriteLine("  {0}", summary.RecordingFileName);
         }
      }

      public Boolean GetRecordingInformation(string recordingFilename, ref string title, ref string subTitle, ref int? seriesNumber, ref int? episodeNumber)
      {
         try
         {
            using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
            {
               Entities.Recording r = tvControlAgent.GetRecordingByFileName(recordingFilename);
               title = r.Title;
               subTitle = r.SubTitle;
               seriesNumber = r.SeriesNumber;
               episodeNumber = r.EpisodeNumber;
            }

            return true;
         }
         catch (Exception ex)
         {
            Log.ErrorException("FTR: ERROR: Exception occured in GetRecordingInformation.", ex);
            return false;
         }
      }

      public Boolean UpdateRecordingEpisodeAndSeason(string recordingFilename, int seasonNumber, int episodeNumber, string episodeName)
      {
         try
         {
            using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
            {
               Entities.Recording r = tvControlAgent.GetRecordingByFileName(recordingFilename);
               r.SeriesNumber = seasonNumber;
               r.EpisodeNumber = episodeNumber;
               r.SubTitle = episodeName;
            }

            return true;
         }
         catch (Exception ex)
         {
            Log.ErrorException("FTR: ERROR: Exception occured in UpdateRecordingEpisodeAndSeason.", ex);
            return false;
         }
      }

      public Boolean UpdateRecordingFilename(string recordingFilename, string newFilename)
      {
         try
         {
            newFilename = Path.GetFileName(newFilename);

            if (recordingFilename == string.Empty)
            {
               Console.WriteLine("    ERROR!  Unable to find recording or errors occured.");
               return false;
            }

            string newRecordingFilename = Path.Combine(Path.GetDirectoryName(recordingFilename), newFilename);

            using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
               return tvControlAgent.ChangeRecordingFile(recordingFilename, newRecordingFilename, null, null);
         }
         catch (Exception ex)
         {
            Log.ErrorException("FTR: ERROR: Exception occured in UpdateRecordingFilename.", ex);
            return false;
         }
      }

      public string GetProgramTitleFromRecordingFilename(string recordingFilename)
      {
         using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
         {
            Entities.Recording r = tvControlAgent.GetRecordingByFileName(recordingFilename);
            return r.Title;
         }
      }

      public string GetRecordingFilename(string partialFilename)
      {
         string result = string.Empty;

         using (TvControlServiceAgent tvControlAgent = new TvControlServiceAgent())
         {
            foreach (Entities.RecordingGroup group in tvControlAgent.GetAllRecordingGroups(Entities.ChannelType.Television, Entities.RecordingGroupMode.GroupByProgramTitle))
               foreach (Entities.RecordingSummary summary in tvControlAgent.GetRecordingsForProgramTitle(Entities.ChannelType.Television, group.ProgramTitle, false))
                  if (summary.RecordingFileName.ToUpper().Contains(partialFilename.ToUpper()))
                  {
                     if (result != string.Empty)
                     {
                        // Console.WriteLine("    ERROR!  Multiple recordings found for filename: {0}", Path.GetFileName(partialFilename));
                        return string.Empty;
                     }
                     else
                        result = summary.RecordingFileName;
                  }
          }

         return result;
      }
   }
}
